#include "floating.h"
#include "ui_floating.h"

Floating::Floating(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Floating)
{
    ui->setupUi(this);

    this->setAttribute(Qt::WA_StyledBackground);

    m_expandTimer = new QTimer();
    m_flodTimer = new QTimer();
    m_expandTimer->setInterval(700);
    m_flodTimer->setInterval(700);

    connect(m_expandTimer, &QTimer::timeout, this, &Floating::expandMenu);
    connect(m_flodTimer, &QTimer::timeout, this, &Floating::flodMenu);

    m_Animation = new QPropertyAnimation(this, "geometry");
    m_Animation->setDuration(600);

    m_isExpand = false;
    m_bDragFlag = false;

    ui->m_titleLeft->setAttribute(Qt::WA_Hover, true);
    ui->m_titleRight->setAttribute(Qt::WA_Hover, true);
    ui->m_menu->setAttribute(Qt::WA_Hover, true);
    ui->m_titleLeft->installEventFilter(this);
    ui->m_titleRight->installEventFilter(this);
    ui->m_menu->installEventFilter(this);

    this->setAttribute(Qt::WA_Hover, true);
    this->installEventFilter(this);

    int horSpacing = static_cast<QGridLayout*>(this->layout())->horizontalSpacing();
    m_posX = this->parentWidget()->width() - ui->m_titleLeft->width() - horSpacing;
    m_posY = 50;

    this->move(m_posX,m_posY);

    setTitleIcon();
}

Floating::~Floating()
{
    delete ui;
}

void Floating::setPosX(int posX)
{
    m_posX = posX;
}

void Floating::setPoxY(int posY)
{
    m_posY = posY;
}

void Floating::adjustParent(int parentWidth)
{
    int horSpacing = static_cast<QGridLayout*>(this->layout())->horizontalSpacing();
    m_posX = parentWidth - ui->m_titleLeft->width() - horSpacing;
    m_posY = 50;

    this->move(m_posX, m_posY);
}

void Floating::expandMenu()
{
    if (m_Animation->state() == QPropertyAnimation::Running) {
        return;
    }

    m_isExpand = true;

    setTitleIcon();

    m_Animation->setStartValue(QRect(m_posX, m_posY,
                                     this->width(), this->height()));
    if (this->x() < this->parentWidget()->width()/2) {
        m_Animation->setEndValue(QRect(m_posX + ui->m_menu->width(), m_posY,
                                       this->width(), this->height()));
    } else {
        m_Animation->setEndValue(QRect(m_posX - ui->m_menu->width(), m_posY,
                                      this->width(), this->height()));
    }

    m_Animation->start();

    m_expandTimer->stop();
}

void Floating::flodMenu()
{
    if (m_Animation->state() == QPropertyAnimation::Running) {
        return;
    }

    m_isExpand = false;

    setTitleIcon();

    m_Animation->setEndValue(QRect(m_posX, m_posY,
                                     this->width(), this->height()));
    if (this->x() < this->parentWidget()->width()/2) {
        m_Animation->setStartValue(QRect(m_posX + ui->m_menu->width(), m_posY,
                                       this->width(), this->height()));
    } else {
        m_Animation->setStartValue(QRect(m_posX - ui->m_menu->width(), m_posY,
                                      this->width(), this->height()));
    }

    m_Animation->start();

    m_flodTimer->stop();
}


bool Floating::eventFilter(QObject *target, QEvent *event)
{
    if (target == ui->m_titleLeft || target == ui->m_titleRight) {
        if (event->type() == QEvent::Enter) {
            if (!m_bDragFlag && !m_isExpand) {
                m_expandTimer->start();
                return QWidget::eventFilter(target, event);
            }
        }

        if (event->type() == QEvent::Leave) {
            m_expandTimer->stop();
        }

        QMouseEvent * mouse = dynamic_cast<QMouseEvent*>(event);
        if (!mouse) {
            return QWidget::eventFilter(target, event);
        }

        if (mouse->button() == Qt::LeftButton && mouse->type() == QEvent::MouseButtonPress)
        {
            m_bDragFlag = true;
            m_expandTimer->stop();

            if (target == ui->m_titleLeft || target == ui->m_titleRight){
                m_pointDrag = mouse->globalPos();
            }
        }

        if (mouse->type() == QEvent::MouseButtonRelease)
        {
            m_bDragFlag = false;
            m_posY = this->y();
            ui->m_menu->show();
            if (target == ui->m_titleLeft) {
                ui->m_titleRight->show();
            }
            else {
                ui->m_titleLeft->show();
            }

            int horSpacing = static_cast<QGridLayout*>(this->layout())->horizontalSpacing();
            if (this->x() < this->parentWidget()->width()/2) {
                m_posX = 0 - ui->m_titleLeft->width() - horSpacing - ui->m_menu->width();
                this->move(m_posX, m_posY);
                return QWidget::eventFilter(target, event);
            }

            m_posX =  this->parentWidget()->width() - ui->m_titleLeft->width() - horSpacing;
            this->move(m_posX, m_posY);
        }

        if (m_bDragFlag &&  mouse->type() == QEvent::MouseMove)
        {
            QPoint toPoint;

            int offsetY= this->parentWidget()->geometry().y();
            int offsetX = this->parentWidget()->geometry().x();

            toPoint = mouse->globalPos() - QPoint(offsetX, offsetY+this->height()/2);

            // y的范围是: (窗口偏移量y + 悬浮窗高度的一半) < x < (窗口偏移量y + 父窗口高度 - 悬浮窗高度的一半)
            int maxPosY = offsetY + this->parentWidget()->height() - this->height()/2;
            int minPosY = offsetY + this->height()/2;
            if (mouse->globalPos().y() > maxPosY || mouse->globalPos().y() < minPosY) {
                toPoint.setY(this->y());
            }

            // x的范围是: (窗口偏移量x) < x < (窗口偏移量x + 父窗口宽度 - title宽度)
            int maxPosX = offsetX + this->parentWidget()->width() -
                          ui->m_titleRight->width();
            int minPosX = offsetX;
            if (mouse->globalPos().x() > maxPosX || mouse->globalPos().x() < minPosX) {
                toPoint.setX(this->x());
            }

            // 当拖动是从左边开始时，位置需要往左移动一点
            if (target == ui->m_titleRight) {
                toPoint.setX(toPoint.x() - this->width() + ui->m_titleRight->width());
            }

            ui->m_menu->hide();
            if (target == ui->m_titleLeft) {
                ui->m_titleRight->hide();
            } else {
                ui->m_titleLeft->hide();
            }

            // 移动的位置 = 鼠标的绝对坐标 -当前窗口的绝对坐标
            this->move(toPoint);
        }
    }

    if (target == ui->m_menu || target == this) {
        if (event->type() == QEvent::Enter) {
            m_flodTimer->stop();
            return QWidget::eventFilter(target, event);
        }

        if (event->type() == QEvent::Leave) {
            if (!m_bDragFlag && m_isExpand) {
                m_flodTimer->start();
            }
        }
    }

    return QWidget::eventFilter(target, event);
}

void Floating::setTitleIcon()
{
    m_isExpand ? ui->m_titleLeft->setProperty("status", "show")
               : ui->m_titleLeft->setProperty("status", "hide");

    if (m_isExpand) {
        ui->m_titleLeft->setProperty("status", "show");
        ui->m_titleRight->setProperty("status", "show");
    } else {
        ui->m_titleLeft->setProperty("status", "hide");
        ui->m_titleRight->setProperty("status", "hide");
    }

    ui->m_titleLeft->style()->polish(ui->m_titleLeft);
    ui->m_titleRight->style()->polish(ui->m_titleRight);
}
